package com.etl.task.handler;

import com.eksframework.commons.core.base.EksCopier;
import com.eksframework.commons.core.base.EksDate;
import com.eksframework.commons.core.base.EksNumber;
import com.eksframework.commons.core.constant.ConstString;
import com.etl.constant.ResultField;
import com.etl.enums.GoodsTypeEnum;
import com.etl.es.document.FilmDocument;
import com.etl.es.document.FilmTicketDocument;
import com.etl.es.document.OrderDocument;
import com.etl.es.repository.FilmTicketRepository;
import com.etl.es.service.FilmService;
import com.etl.extract.DatabaseBuilder;
import com.etl.extract.ScheduleTask;
import com.etl.extract.SqlQuery;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 影票处理类
 *
 * @author: chenfenghai
 * @version: 1.0
 * @date: 2020-10-30 9:55
 */
@Slf4j
@Component
public class FilmTicketHandler {

    @Autowired
    DatabaseBuilder databaseBuilder;

    @Autowired
    FilmService filmService;

    @Autowired
    FilmTicketRepository filmTicketRepository;

    /**
     * 查询销售排期列表
     *
     * @param scheduleTask 调度任务信息
     * @param parameterMap SQL参数MAP
     * @return List
     */
    public List<Map<String, String>> findSalePlanList(
            ScheduleTask scheduleTask, Map<String, Object> parameterMap) {
        SqlQuery extractQuery = SqlQuery.builder()
                .id("com.etl.task.mapper.SaleOrderMapper.findSalePlanList")
                .parameterObject(parameterMap)
                .build();
        return databaseBuilder.queryData(scheduleTask, extractQuery);
    }

    /**
     * 查询退票排期列表
     *
     * @param scheduleTask 调度任务信息
     * @param parameterMap SQL参数MAP
     * @return List
     */
    public List<Map<String, String>> findRejectPlanList(
            ScheduleTask scheduleTask, Map<String, Object> parameterMap) {
        SqlQuery extractQuery = SqlQuery.builder()
                .id("com.etl.task.mapper.RejectOrderMapper.findRejectPlanList")
                .parameterObject(parameterMap)
                .build();
        return databaseBuilder.queryData(scheduleTask, extractQuery);
    }

    /**
     * 保存ES影票文档列表
     *
     * @param documentList ES影票文档列表
     */
    public void saveFilmTicketDocumentList(List<FilmTicketDocument> documentList) {
        if (CollectionUtils.isEmpty(documentList)) {
            return;
        }
        filmTicketRepository.saveAll(documentList);
    }

    /**
     * 建造ES影票文档列表
     *
     * @param orderDocument 订单文档
     * @param goodsMap      查询商品结果MAP
     * @param planMap       查询排期结果MAP
     * @return List-FilmTicketDocument
     */
    public List<FilmTicketDocument> buildFilmTicketDocumentList(
            OrderDocument orderDocument, Map<String, String> goodsMap, Map<String, String> planMap) {
        if (Objects.isNull(goodsMap)) {
            return Lists.newArrayList();
        }
        return Stream.of(GoodsTypeEnum.getFilmTicketValues())
                .map(goodsTypeEnum -> buildFilmTicketDocument(
                        orderDocument, goodsMap, planMap, goodsTypeEnum))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 建造ES影票文档
     *
     * @param orderDocument 订单文档
     * @param goodsMap      查询商品结果MAP
     * @param planMap       查询排期结果MAP
     * @param goodsTypeEnum 商品类型枚举
     * @return FilmTicketDocument
     */
    public FilmTicketDocument buildFilmTicketDocument(OrderDocument orderDocument,
                                                      Map<String, String> goodsMap,
                                                      Map<String, String> planMap,
                                                      GoodsTypeEnum goodsTypeEnum) {
        if (Objects.isNull(goodsMap) || Objects.isNull(planMap)) {
            return null;
        }
        BigDecimal goodsPrice = EksNumber.of(goodsMap.get(goodsTypeEnum.getPriceField()))
                .toEksConverter().toBigDecimal();
        int goodsCount = EksNumber.of(goodsMap.get(goodsTypeEnum.getCountField()))
                .toEksConverter().intValue();
        if (BigDecimal.ZERO.compareTo(goodsPrice) == 0 && goodsCount == 0) {
            return null;
        }

        // 放映时间
        EksDate sessionDateTime = EksDate.of(planMap.get(ResultField.SHOW_TIME));
        // 营业日期
        EksDate businessDateTime = sessionDateTime.copy().withBusinessDateTime(false);
        // 电影信息
        FilmDocument filmDocument = filmService.buildFilmDocument(
                planMap.get(ResultField.MOVIE_CODE), planMap.get(ResultField.MOIVE_NAME));

        FilmTicketDocument filmTicket = EksCopier.copy(orderDocument, FilmTicketDocument.class);
        filmTicket.setOrderId(StringUtils.joinWith(
                ConstString.UNDERLINE, filmTicket.getOrderId(), goodsTypeEnum.getCode()));

        filmTicket.setFilmCode(filmDocument.getFilmCode());
        filmTicket.setFilmName(filmDocument.getFilmName());
        filmTicket.setScreenCode(planMap.get(ResultField.HALL_CODE));
        filmTicket.setScreenTypeName(planMap.get(ResultField.HALL_TYPE_NAME));
        filmTicket.setSessionCode(planMap.get(ResultField.PLAN_CODE));

        filmTicket.setSessionYear(businessDateTime.toLocalDate().getYear() + EksDate.CN_YEAR);
        filmTicket.setSessionMonth(businessDateTime.toString(EksDate.PATTERN_YYYYMM_CN));
        filmTicket.setSessionDay(businessDateTime.toString(EksDate.PATTERN_YYYYMMDD_CN));
        filmTicket.setSessionHour(sessionDateTime.toString(EksDate.PATTERN_YYYYMMDDHH_CN));
        filmTicket.setSessionDateTime(sessionDateTime.toDate());

        filmTicket.setGoodsPrice(goodsPrice.doubleValue());
        filmTicket.setGoodsCount(goodsCount);

        filmTicket.setGoodsType(goodsTypeEnum.getCode());
        filmTicket.setGoodsTypeName(goodsTypeEnum.getText());
        return filmTicket;
    }
}
